<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <meta name="keywords" content="2048,小游戏">
    <meta name="description" content="本页面是2048小游戏">
    <title>2的11次方</title>
    <div th:replace="tools/_fragments-tools::basicrefrence"></div>
</head>
<body class="unselect" id = "body">

<nav th:replace="tools/_fragments-tools::head"></nav>


<div style="padding-top: 50px;padding-bottom: 50px;padding-left: 15%;padding-right: 15%;">
    <div class="ui center aligned mobile stackable segment">
        <div class="ui container">
            <div class="ui middle aligned center aligned mobile stackable grid">
                <div class="column">
                    <h1 class="ui teal image header">
                        <img id="startButton" src="../images/2048/2048button.gif" class="image" draggable="false">
                        <div id = "scoreSegment" class="content">
                            0
                        </div>
                    </h1>
                    <form class="ui large form" method="post" action="#">
                        <div id="mapSegment" class="ui stacked segment">

                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>

<div class="ui tiny modal" _msthidden="5">
    <i class="close icon"></i>
    <div class="header" _msttexthash="152334" _msthidden="1" _msthash="383">
        你已经炸了hhhhh
    </div>
    <div class="image content" _msthidden="2">
        <div id="endSegment" class="image" _msttexthash="888004" _msthidden="1" _msthash="384">
            <i class="close icon"></i>
        </div>
        <div class="description" _msttexthash="947076" _msthidden="1" _msthash="385">
            <div class="ui input">
                <input id="person" type="text" placeholder="留下你的传奇" data-listener-added_2e34a347="true">
            </div>
        </div>
    </div>
    <div class="actions" _msthidden="2">
        <div class="ui green button" _msttexthash="14989" _msthidden="1" _msthash="387" onclick="submitScore()">OK</div>
    </div>
</div>

<div class="ui mini modal">
    <div class="header">
        嗯？！不留下个名字吗？
    </div>
    <div class="actions">
        <div class="ui button" onclick="showFailModal()">OK</div>
    </div>
</div>

<!---缓存--->
<img src="../images/2048/0.png" className="image" draggable="false" style="visibility: hidden">
<img src="../images/2048/2.png" className="image" draggable="false" style="visibility: hidden">
<img src="../images/2048/4.png" className="image" draggable="false" style="visibility: hidden">
<img src="../images/2048/8.png" className="image" draggable="false" style="visibility: hidden">
<img src="../images/2048/16.png" className="image" draggable="false" style="visibility: hidden">
<img src="../images/2048/32.png" className="image" draggable="false" style="visibility: hidden">
<img src="../images/2048/64.png" className="image" draggable="false" style="visibility: hidden">
<img src="../images/2048/128.png" className="image" draggable="false" style="visibility: hidden">
<img src="../images/2048/256.png" className="image" draggable="false" style="visibility: hidden">
<img src="../images/2048/512.png" className="image" draggable="false" style="visibility: hidden">
<img src="../images/2048/1024.png" className="image" draggable="false" style="visibility: hidden">



<footer th:replace="tools/_fragments-tools::foot"></footer>

<div id="toolDiv"  class="ui vertical icon buttons  m-fixed">
    <button id="howToUse" type="button" class="ui vertical teal button w" >排行</button>
    <div style="width: 250px" class="ui flowing popup top transition hidden startFlattery">
        <table id="rankingList">
        </table>
    </div>
</div>

<script type="text/javascript">

    $('.tiny.modal').modal({
        allowMultiple: true, // 允许多个模态框同时打开
        closable: false, // 禁止通过点击dimmer关闭模态框
    });
    $('.mini.modal').modal({
        allowMultiple: true, // 允许多个模态框同时打开
        closable: false, // 禁止通过点击dimmer关闭模态框
    });

    var rankingListTable = $("#rankingList");
    function flushRankingList(rankingList){
        rankingListTable.empty();
        rankingListTable.append("<tr>\n" +
            "                <td><h2 style=\"color: darkcyan\">名称</h2></td>\n" +
            "                <td><h2 style=\"color: darkcyan\">分数</h2></td>\n" +
            "            </tr>");

        for(let i = 0; i < rankingList.length; i++) {
            rankingListTable.append("<tr>\n" +
                "                <td><h4 style=\"color: darkcyan\">" + rankingList[i].person + "</h4></td>\n" +
                "                <td><h4 style=\"color: darkcyan\">" + rankingList[i].score + "</h4></td>\n" +
                "            <tr/>")
        }
    }

    function getAndFlushRankingList () {
        $.ajax({
            url: "/tools/2048/getScoreFirstFive",
            type: "get",
            success: function (resp) {
                if (resp.code === 1) {
                    flushRankingList(resp.data);
                }
            }
        })
    }

    /**
     * 禁止右键菜单
     * @returns {boolean}
     */
    document.oncontextmenu = function () {
        return false;
    }

    // 屏幕宽度小于500为手机
    var isPhone = $(window).width() < 500;
    //双击时间
    var time = 0;
    //随机数概率基准
    const BASE_NUMBER = 5;
    const APPEAR_TWO = 4;
    const INIT_COUNT = 2;
    // 能否出现在已有位置
    const LAST_POSITION_BASE = 5;
    const LAST_POSITION_CHANCE = 1;
    // 地图显示对象
    var mapSegment = $("#mapSegment");
    var scoreSegment = $("#scoreSegment");
    var endSegment = $("#endSegment");
    // 移动阈值
    const MOVE_LIMIT = 10;
    const DATA_LIST = [2, 4];
    // 地图数据
    const MAX_ROW = 4;
    const MAX_COL = 4;
    var map = [
        [0, 0, 0, 0],
        [0, 0, 0, 0],
        [0, 0, 0, 0],
        [0, 0, 0, 0],
    ]
    var lastMap = [
        [0, 0, 0, 0],
        [0, 0, 0, 0],
        [0, 0, 0, 0],
        [0, 0, 0, 0],
    ];
    // 分数
    var score = 0;
    // 启动状态
    var start = false;
    // 本轮是否有产生移动或合并
    var moveOrMerge = false;

    var visualMap = "";
    for (var i = 0; i < MAX_ROW; ++i) {
        visualMap += "<div className=\"field\">";
        for (var j = 0; j < MAX_COL; ++j) {
            visualMap +=
                "<img src=\"../images/2048/0.png\" className=\"image\" draggable=\"false\" wide='35px' height='35px' style='border: solid;margin-left: 2px'>";
        }
        visualMap += "</div>";
    }
    mapSegment.html(visualMap);

    /**
     * 提交分数
     */
    var nameInput = $("#person");
    function submitScore() {
        let person = nameInput.val();
        if (person == null || person.length === 0) {
            $('.mini.modal').modal('show');
            return;
        }
        $.ajax({
            url: '/tools/2048/addScore',
            type: 'post',
            data: {
                score :score,
                person :person
            },
            success: function (res) {
                $('.tiny.modal').modal('hide');
                start = false;
                score = 0;
                getAndFlushRankingList();
            }
        })
    }

    /**
     * 显示失败模态框
     */
    function showFailModal() {
        $('.mini.modal').modal('hide');
        $('.tiny.modal').modal('show');
    }



    /**
     * 点击记录当前坐标
     * @type {number}
     */
    var startX = 0;
    var startY = 0;
    document.onmousedown = function (event) {
        // 不是左键不管
        if (isPhone || !start || event.button !== 0) {
            return;
        }
        startX = event.pageX;
        startY = event.pageY;
    }
    /**
     * 松开计算移动值
     * @param event
     */
    document.onmouseup = function (event) {
        // 不是左键不管
        if (isPhone || !start || event.button !== 0) {
            return;
        }
        // 获取坐标移动值
        var x = startX - event.pageX;
        var y = startY - event.pageY;
        // 获取坐标移动绝对值
        var absX = x > 0 ? x : -x;
        var absY = y > 0 ? y : -y;
        // 移动过小不管
        if (absX > 30 || absY > MOVE_LIMIT) {
            //左右移动
            if (absX > absY) {
                if (x > 0) {
                    leftMerge();
                } else {
                    rightMerge();
                }
            } else {
                if (y > 0) {
                    upMerge();
                } else {
                    downMerge();
                }
            }
            if (isFail()) {
                start = false;
                time = 0;
                var rank = 0;
                $.ajax({
                    url: '/tools/2048/getRank',
                    type: 'post',
                    data: {
                        score:score
                    },
                    success: function (res) {
                        rank = res.data;
                        endSegment.text("你获得了" + score + "分，打败了" + rank + "%的人")
                        $('.tiny.modal').modal('show');
                    }
                })
            }else if (moveOrMerge){
                if (isFull()) {
                    createNumber(1, APPEAR_TWO, map);
                } else if (Math.floor(Math.random() * LAST_POSITION_BASE) < LAST_POSITION_CHANCE) {
                    createNumber(1, APPEAR_TWO, lastMap);
                }else {
                    createNumber(1, APPEAR_TWO, map);
                }
                showMap();
            }
            moveOrMerge = false;
        }
    }

    $("#body").click(function (even) {
        if (!isPhone || !start) {
            return;
        }
        if (time === 0) {
            time = new Date().getTime();
            return;
        }
        var intermittent = new Date().getTime() - time;
        time = 0;
        console.log(intermittent);
        if (intermittent < 300) {
            var dx = even.pageX / $(document.body).width();
            var dy = even.pageY / $(document.body).height() * 1.3;

            var verdictX = dx - 0.5;
            var verdictY = dy - 0.5;

            var absVerdictX = verdictX > 0? verdictX : -verdictX;
            var absVerdictY = verdictY > 0? verdictY : -verdictY;

            if (absVerdictX > absVerdictY) {
                if (verdictX < 0) {
                    leftMerge();
                }else {
                    rightMerge();
                }
            }else {
                if (verdictY < 0) {
                    upMerge();
                }else{
                    downMerge();
                }
            }
            if (isFail()) {
                var rank = 0;
                $.ajax({
                    url: '/tools/2048/getRank',
                    type: 'post',
                    data: {
                        score:score
                    },
                    success: function (res) {
                        rank = res.data;
                        endSegment.text("你获得了" + score + "分，打败了" + rank + "%的人")
                        $('.tiny.modal').modal('show');
                    }
                })
            }else if (moveOrMerge){
                if (isFull()) {
                    createNumber(1, APPEAR_TWO, map);
                } else if (Math.floor(Math.random() * LAST_POSITION_BASE) < LAST_POSITION_CHANCE) {
                    createNumber(1, APPEAR_TWO, lastMap);
                }else {
                    createNumber(1, APPEAR_TWO, map);
                }
                showMap();
            }
            moveOrMerge = false;
        }

    });

    /**
     * 判失败
     */
    function isFail() {
        for (var i = 0; i < MAX_ROW; ++i) {
            for (var j = 0; j < MAX_COL; ++j) {
                if (map[i][j] === 0) return false;
            }
        }
        for (var i = 0; i < MAX_ROW; ++i) {
            for (var j = 0; j < MAX_COL; ++j) {
                if (i + 1 < MAX_ROW && map[i][j] === map[i + 1][j]) return false;
                if (j + 1 < MAX_ROW && map[i][j] === map[i][j + 1]) return false;
            }
        }
        return true;
    }

    /**
     * 判满
     */
    function isFull() {
        var fullFlag = true;
        for (var i = 0; i < MAX_ROW; i++) {
            for (var j = 0; j < MAX_COL; j++) {
                if (map[i][j] !== 0 && lastMap[i][j] === 0) {
                    lastMap[i][j] = map[i][j];
                    if (lastMap[i][j] === 0 ) fullFlag = false;
                }
            }
        }
        return fullFlag;
    }

    /**
     * 更新可视地图
     */
    function showMap() {
        mapSegment.empty();
        var visualMap = "";
        for (var i = 0; i < MAX_ROW; ++i) {
            visualMap += "<div className=\"field\">";
            for (var j = 0; j < MAX_COL; ++j) {
                // lastMap=map
                lastMap[i][j] = map[i][j];
                visualMap +=
                    "<img src=\"../images/2048/" +
                    map[i][j] +
                    ".png\" className=\"image\" draggable=\"false\" wide='35px' height='35px' style=\"border: solid;margin-left: 2px\">";
            }
            visualMap += "</div>";
        }
        mapSegment.html(visualMap);
        scoreSegment.html("" + score);
    }

    /**
     * 随机生成一个数据在地图空位上
     * @{param} chance 2出现的概率（chance / 5）
     */
    function createNumber(count, chance, baseMap) {
        while (count > 0) {
            var x = Math.floor(Math.random() * MAX_ROW);
            var y = Math.floor(Math.random() * MAX_ROW);
            while (baseMap[x][y] !== 0) {
                x = Math.floor(Math.random() * MAX_ROW);
                y = Math.floor(Math.random() * MAX_ROW);
            }
            map[x][y] = (Math.floor(Math.random() * BASE_NUMBER) <= chance) ? 2 : 4;
            --count;
        }
    }

    /**
     * 初始化地图
     */
    $("#startButton").click(function(even) {
        if (start) return;
        for (var i = 0; i < MAX_ROW; ++i) {
            for (var j = 0; j < MAX_COL; ++j) {
                map[i][j] = 0;
            }
        }
        createNumber(INIT_COUNT, BASE_NUMBER, map);
        showMap();
        score = 0;
        start = true;
        event.stopPropagation();
    });

    function addScore(newDate) {
        var add = 0;
        switch (newDate){
            case 4:    add = 1;  break;
            case 8:    add = 2;  break;
            case 16:   add = 3;  break;
            case 32:   add = 4;  break;
            case 64:   add = 5;  break;
            case 128:  add = 6;  break;
            case 256:  add = 7;  break;
            case 512:  add = 8;  break;
            case 1024: add = 9;  break;
            case 2048: add = 10; break;
            case 4096: add = 11; break;
        }
        score += add;
        moveOrMerge = true;
    }

    /**
     * 向左移动
     */
    function leftMove(i) {
        // 移动
        for (var j = 1; j < MAX_COL; ++j) {
            if (map[i][j] === 0) continue;
            // 全部左移
            var k = j;
            while (--k >= 0 && map[i][k] === 0) ;
            k++;
            if (k === j) continue;
            map[i][k] = map[i][j];
            map[i][j] = 0;
            moveOrMerge = true;
        }

    }

    /**
     * 向左合并
     */
    function leftMerge() {
        for (var i = 0; i < MAX_ROW; ++i) {
            // 移动
            leftMove(i);
            // 合并
            for (var j = 1; j < MAX_COL; ++j) {
                // 合并到0就可以结束
                if (map[i][j] === 0) break;
                // 相同合并
                if (map[i][j] === map[i][j - 1]) {
                    map[i][j - 1] += map[i][j];
                    addScore(map[i][j - 1]);
                    if(map[i][j - 1] === 4096) {
                        map[i][j - 1] = 0;
                    }
                    map[i][j] = 0;
                    j++;
                }
            }
            // 移动
            leftMove(i);
        }
    }

    /**
     * 向右移动
     */
    function rightMove(i) {
        // 移动
        for (var j = MAX_COL - 2; j >= 0; --j) {
            if (map[i][j] === 0) continue;
            // 全部右移
            var k = j;
            while (++k < MAX_COL && map[i][k] === 0) ;
            k--;
            if (k === j) continue;
            map[i][k] = map[i][j];
            map[i][j] = 0;
            moveOrMerge = true;
        }

    }

    /**
     * 向右合并
     */
    function rightMerge() {
        for (var i = 0; i < MAX_ROW; ++i) {
            rightMove(i);

            // 合并
            for (var j = MAX_COL - 2; j >= 0; --j) {
                // 合并到0就可以结束
                if (map[i][j] === 0) break;
                // 相同合并
                if (map[i][j] === map[i][j + 1]) {
                    map[i][j + 1] += map[i][j];
                    addScore(map[i][j + 1]);
                    if (map[i][j + 1] === 4096) {
                        map[i][j + 1] = 0;
                    }
                    map[i][j] = 0;
                    j--;
                }
            }
            // 移动
            rightMove(i);
        }
    }

    /**
     * 向上移动
     */
    function upMove(j) {

        // 移动
        for (var i = 1; i < MAX_ROW; ++i) {
            if (map[i][j] === 0) continue;
            // 全部上移
            var k = i;
            while (--k >= 0 && map[k][j] === 0) ;
            k++;
            if (k === i) continue;
            map[k][j] = map[i][j];
            map[i][j] = 0;
            moveOrMerge = true;
        }
    }

    /**
     * 向上合并
     */
    function upMerge() {
        for (var j = 0; j < MAX_COL; ++j) {
            upMove(j);

            var lastNumber = map[0][j];
            var lastIndex = 0;
            // 合并
            for (var i = 1; i < MAX_ROW; ++i) {
                // 合并到0就可以结束
                if (map[i][j] === 0) break;
                // 相同合并
                if (map[i][j] === map[i - 1][j]) {
                    map[i - 1][j] += map[i][j];
                    addScore(map[i - 1][j]);
                    if(map[i - 1][j] === 4096) {
                        map[i - 1][j] = 0;
                    }
                    map[i][j] = 0;
                    i++;
                }
            }
            // 移动
            upMove(j);
        }

    }

    /**
     * 向下移动
     */
    function downMove(j) {
        // 移动
        for (var i = MAX_ROW - 2; i >= 0; --i) {
            if (map[i][j] === 0) continue;
            // 全部下移
            var k = i;
            while (++k < MAX_ROW && map[k][j] === 0) ;
            k--;
            if (k === i) continue;
            map[k][j] = map[i][j];
            map[i][j] = 0;
            moveOrMerge = true;
        }
    }

    /**
     * 向下合并
     */
    function downMerge() {
        for (var j = 0; j < MAX_COL; ++j) {
            downMove(j);
            var lastNumber = map[MAX_ROW - 1][j];
            var lastIndex = MAX_ROW - 1;
            // 合并
            for (var i = MAX_ROW - 2; i >= 0; --i) {
                // 合并到0就可以结束
                if (map[i][j] === 0) break;
                // 相同合并
                if (map[i][j] === map[i + 1][j]) {
                    map[i + 1][j] += map[i][j];
                    addScore(map[i + 1][j]);
                    if(map[i + 1][j] === 4096) {
                        map[i + 1][j] = 0;
                    }
                    map[i][j] = 0;
                    i--;
                }
            }
            // 移动
            downMove(j);
        }

    }

    $("#howToUse").popup({
      popup:$(".howToUse-pop.popup"),
      on:'click',
      position:'right center'
    })

    $(function() {
        getAndFlushRankingList();
    })

</script>


</body>
</html>